using System;
using System.Collections.Generic;

/// <summary>
/// Summary description for GoogleChart
/// </summary>
public class GoogleChart
{
    static public List<String> getCharts( Data.Page thisPage, 
                Boolean wantColumnCharts, Boolean wantRowCharts, 
                Boolean wantMultiColumn, Boolean wantMultiRow )
    {
        List<String> output = new List<String>();
        GoogleChart googleChart = new GoogleChart();
        
        String chBaseURL = "http://chart.apis.google.com/chart?";
        String chGradient = "chf=c,lg,45,c0c0c0,0,ffffff,0.75|bg,s,ffffff";

        if( wantColumnCharts )
        {
            output.Add(getSubtitle(thisPage, "Column Chart"));
            output.Add( "<br />");
            for (int numericColumnIndex = 0, columnCount = thisPage.GetNumericColumnCount();
                    numericColumnIndex < columnCount ; numericColumnIndex++ )
            {
                String chData = GetData( thisPage, true, numericColumnIndex );
                String chTitle = GetChartTitle( thisPage, true, numericColumnIndex, false, true );
                String chMarkers = GetMarkersColumn( thisPage, numericColumnIndex );
                String chLegend = GetDataRowNames(thisPage);

                String chWholeThing =
                        chBaseURL + "" + "cht=bvs"
                        + "&" + chTitle 
                        + "&" + chGradient 
                        + "&" + GetSize( "800", "300" ) 
                        + "&" + chData;

                output.Add( "<img alt='chart' src='" + chWholeThing + "' /><br />" );
                output.Add( getPositionInfo( thisPage, "c", numericColumnIndex, false ));
            }
            output.Add("<br />");
        }

        if( wantRowCharts )
        {
            output.Add(getSubtitle(thisPage, "Row Charts"));
            output.Add("<br />");
            for (int rowIndex = 0, rowCount = thisPage.GetRowCount();
                    rowIndex < rowCount  ; rowIndex++ )
            {
                String chData= GetData( thisPage, false, rowIndex ); 
                String chTitle = GetChartTitle(thisPage, false, rowIndex, false, true );

                String chWholeThing = 
                        chBaseURL 
                        + "" + "cht=bvs" // "cht=p3" 
                        + "&" + chGradient 
                        + "&" + chTitle 
                        + "&" + GetSize("800", "300") 
                        + "&" + chData ; // + "&" + googleChart.GetPieLabelsColumn(thisPage); 

                output.Add( "<img alt='chart' src='" + chWholeThing  + "' /><br />" );
                output.Add(getPositionInfo(thisPage, "r", rowIndex, false));
            }
            output.Add("</br>");
        }

        if( wantMultiColumn  )
        {
            output.Add(getSubtitle(thisPage, "All Columns"));

            String chType = "cht=lc";
            String chData = GetDataColumns( thisPage );
            String chSize = GetSize("600", "100");
            String chLegend = GetDataColumnNames(thisPage);

            String chWholeThing = chBaseURL 
                            + "" + chSize 
                            + "&" + chType 
                            + "&" + chData
                            + "&" + chLegend
                            + "&" + GetDataColumnsColors( thisPage );

            output.Add( "<br /><img alt='chart' src='" + chWholeThing  + "' />" );
        }

        if( wantMultiRow  )
        {
            output.Add(getSubtitle(thisPage, "All Columns"));

            String chType = "cht=lc";
            String chData = GetDataRows( thisPage );
            String chSize = GetSize("600", "100");
            String chLegend = GetDataRowNames(thisPage);

            String chWholeThing = chBaseURL 
                            + "" + chSize 
                            + "&" + chType 
                            + "&" + chData
                            + "&" + chLegend
                            + "&" + GetDataRowsColors( thisPage );

            output.Add( "<br /><img alt='chart' src='" + chWholeThing  + "' />" );
        }
        return output;
    }
    static private String getSubtitle( Data.Page thisPage, String chartGroupSubtitle )
    {
        String returnValue = "<br /><label class='DlgTitle'>" 
            + thisPage.GetPageCaption() 
            + " - " 
            + chartGroupSubtitle
            + "</label><br />";

        return returnValue;
    }

    static private String getPositionInfo(Data.Page thisPage, String axis, int positionIndex, Boolean preferTallLayout )
    {
        // return a table
        String retVal = "";

        if (axis.StartsWith("c", StringComparison.CurrentCultureIgnoreCase))
        {
            retVal += thisPage.GetNumericColumnName(positionIndex);
            retVal += "<table>";
            retVal += "<tr>";
            for (int rowIndex = 0, rowCount = thisPage.GetRowCount(); rowIndex < rowCount; rowIndex++)
            {
                retVal += "<td>";
                retVal += thisPage.GetRowLabelValue(rowIndex) ;
                retVal += "</td>";
            }
            retVal += "</tr>";
            retVal += "<tr>";
            for (int rowIndex = 0, rowCount = thisPage.GetRowCount(); rowIndex < rowCount; rowIndex++)
            {
                retVal += "<td>";
                retVal += thisPage.GetNumericCellContents(rowIndex, positionIndex, true);
                retVal += "</td>";
            }
            retVal += "</tr>";
            retVal += "</table><br />";
        }
        else if (axis.StartsWith("r", StringComparison.CurrentCultureIgnoreCase))
        {
            retVal += thisPage.GetRowLabelValue(positionIndex);
            retVal += "<table>";
            retVal += "<tr>";
            for (int colIndex = 0, colCount = thisPage.GetNumericColumnCount(); colIndex < colCount; colIndex++)
            {
                retVal += "<td>";
                retVal += thisPage.GetNumericColumnName(colIndex);
                retVal += "</td>";
            }
            retVal += "</tr>";
            retVal += "<tr>";
            for (int colIndex = 0, colCount = thisPage.GetNumericColumnCount(); colIndex < colCount; colIndex++)
            {
                retVal += "<td>";
                retVal += thisPage.GetNumericCellContents(positionIndex, colIndex, true);
                retVal += "</td>";
            }
            retVal += "</tr>";
            retVal += "</table><br />";
        }
        else
            return "";

        return retVal;
    }

    static String[] colors =
        {
            "4572a7",
            "aa4643",
            "89a54e",
            "71588f",
            "4198af",
            "db843d",
            "9999ff",
            "993366",
            "ffffcc",
            "ccffff",
            "660066",
            "ff8080",
            "0066cc",
            "ccccff"
        };

    static String[] alertColors =
        {
            "4572a7",
            "aa4643",
            "89a54e",
            "71588f",
            "4198af",
            "db843d",
            "9999ff",
            "993366",
            "ffffcc",
            "ccffff",
            "660066",
            "ff8080",
            "0066cc",
            "ccccff"
        };

    static Double overallMax = Double.MaxValue;

    static String GetRowLabels(Data.Page obj)
        {
            String retVal = "";

            for (int rowIndex = 0, rowCount = obj.GetRowCount();
                rowIndex < rowCount ; rowIndex++)
            {
                retVal += "|" + obj.GetRowLabelValue(rowIndex);
            }
            return retVal; // "|Mar|Apr|May|June|July|" ;
        }
    static String GetColumnLabels(Data.Page obj)
        {
            String retVal = "chxl=0:";

            for (int numericColumnIndex = 0, numericCount = obj.GetNumericColumnCount();
                        numericColumnIndex < numericCount; numericColumnIndex++)
            {
                retVal += "|" + obj.GetNumericColumnName(numericColumnIndex);
            }

            retVal += "||" + overallMax.ToString();

            return retVal; // "||50+Kb"; 
        }

    static String GetPieLabelsColumn(Data.Page obj)
        {
            String retVal = "chl=";
            for (int numericColumnIndex = 0, numericCount = obj.GetNumericColumnCount();
                        numericColumnIndex < numericCount; numericColumnIndex++)
            {
                if (numericColumnIndex > 0)
                    retVal += "|";
                retVal += obj.GetNumericColumnName(numericColumnIndex);
            }
            return retVal;
        }

    static String GetMarkersColumn(Data.Page obj, int numericColumnIndex)
        {
            String[] markers = { "c", "d", "o", "s", "a", "v", "h", "x", "c", "d", "o", "s", "a" };  // different googlechart markers , need up to 10
            String retVal = "chm=";
            for (int rowIndex = 0, rowCount = obj.GetRowCount();
                rowIndex < rowCount ; rowIndex++)
            {
                String alertLevel = obj.GetAlertLevel(rowIndex, numericColumnIndex);
                int intAlertLevel ;
                Boolean success = int.TryParse( alertLevel, out intAlertLevel );
                if ( success && intAlertLevel > -1 && intAlertLevel < 10)
                {
                    if (rowIndex > 0)
                        retVal += "|";

                    retVal += markers[intAlertLevel] + ",";
                    retVal += alertColors[intAlertLevel];

                    // data set index
                    retVal += "," + "0";

                    // rowIndex to identify the data point
                    retVal += "," + rowIndex.ToString();

                    // size of marker
                    retVal += ",10.0";
                }
            }
            return retVal;
        }
    static String GetDataRowNames(Data.Page thisPage)
        {
            String series = "chdl=";
            for (int rowIndex = 0, rowCount = thisPage.GetRowCount();
                rowIndex < rowCount ; rowIndex++)
            {
                if (rowIndex > 0)
                    series += "|";
                series += thisPage.GetRowLabelValue(rowIndex);
            }
            return series;
        }
    static String GetDataRows(Data.Page thisPage)
        {
            String series = "chd=s:";
            for (int rowIndex = 0, rowCount = thisPage.GetRowCount();
                rowIndex < rowCount ; rowIndex++)
            {
                if (rowIndex > 0)
                    series += ",";
                series += GetNormalizedDataFromRow(thisPage, rowIndex);
            }
            return series;
        }
    static String GetDataRowsColors(Data.Page thisPage)
        {
            String series = "chco=";
            int colorIndex = 0;
            for (int rowIndex = 0, rowCount = thisPage.GetRowCount();
                rowIndex < rowCount ; rowIndex++)
            {
                if (rowIndex > 0)
                    series += ",";
                String thisColor = colors[colorIndex];

                series += thisColor;

                if (++colorIndex == colors.Length )
                    colorIndex = 0;
            }
            return series;
        }
    static String GetDataColumnNames(Data.Page thisPage)
        {
            String series = "chdl=";
            for (int colIndex = 0, colCount = thisPage.GetNumericColumnCount();
                        colIndex < colCount; colIndex++)
            {
                if (colIndex > 0)
                    series += "|";

                series += thisPage.GetNumericColumnName(colIndex);
            }
            return series;
        }
    static String GetDataColumns(Data.Page thisPage)
        {
            String series = "chd=s:";
            for (int colIndex = 0, colCount = thisPage.GetNumericColumnCount();
                        colIndex < colCount; colIndex++)
            {
                if (colIndex > 0)
                    series += ",";

                series += GetNormalizedDataFromColumn(thisPage, colIndex);
            }
            return series;
        }
    static String GetDataColumnsColors(Data.Page thisPage) //  "chco=ff0000,00ff00";
        {
            int colorIndex = 0;

            String series = "chco=";
            for (int colIndex = 0, colCount = thisPage.GetNumericColumnCount();
                        colIndex < colCount; colIndex++)
            {
                String thisColor = colors[colorIndex];

                if (colIndex > 0)
                    series += ",";
                series += thisColor;

                if (++colorIndex == colors.Length )
                    colorIndex = 0;
            }
            return series;
        }

    static String GetData(Data.Page Object1, Boolean columns, int position)
        {
            String retVal = "chd=s:"; // s:ABCDEFGHI";
            if (columns)
                retVal += GetNormalizedDataFromColumn(Object1, position); // "s:ABCDEFGHI";
            else
                retVal += GetNormalizedDataFromRow(Object1, position);

            return retVal;
        }

    static String GetNormalizedDataFromColumn(Data.Page obj, int columnIndex)
        {
            // return "chd=s:helloworld";
            String retVal = ""; // "chd=s:"; // s:ABCDEFGHI";

            Double max = overallMax;

            if (max == Double.MaxValue )
            {
                String strMax = obj.GetAggregateValue("column", columnIndex, "maximum", false);
                if (strMax.Length > 0)
                {
                    Double.TryParse(strMax, out max);
                }
            }

            for (int rowIndex = 0, rowCount = obj.GetRowCount();
                rowIndex < rowCount ; rowIndex++)
            {
                retVal += "";

                String strVal = obj.GetNumericCellContents(rowIndex, columnIndex, false);
                if (strVal.Length > 0)
                {
                    Double val;
                    Boolean success = double.TryParse(strVal, out val);
                    if (success && val > 0)
                        retVal += simpleEncode(val, max);
                    else
                        retVal += "A";
                }
                else
                    retVal += "A";
            }


            return retVal;
        }

    static private String GetNormalizedDataFromRow(Data.Page obj, int rowIndex)
        {
            String retVal = "";

            Double max = overallMax;

            if (max == Double.MaxValue )
            {
                String strMax = obj.GetAggregateValue("row", rowIndex, "maximum", false);
                if (strMax.Length > 0)
                {
                    double.TryParse(strMax, out max);
                }
            }

            for (int columnIndex = 0, columnCount = obj.GetNumericColumnCount();
                columnIndex < columnCount; columnIndex++)
            {
                retVal += "";

                String strVal = obj.GetNumericCellContents(rowIndex, columnIndex, false);
                if (strVal.Length > 0)
                {
                    Double val;
                    Boolean success = double.TryParse(strVal, out val);
                    if (success && val > 0)
                        retVal += simpleEncode(val, max);
                    else
                        retVal += "A";
                }
                else
                    retVal += "A";
            }
            return retVal;
        }

    static String GetChartTitle(Data.Page obj, Boolean columns, int positionIndex, Boolean pageCaption, Boolean positionCaption)
        {
            String retVal = "chtt=";
            if (pageCaption)
                retVal += obj.GetPageCaption();

            if (positionCaption)
            {
                if (pageCaption)
                    retVal += "|";
                if (columns)
                {
                    retVal += obj.GetNumericColumnName(positionIndex);
                }
                else
                {
                    retVal += obj.GetRowLabelValue(positionIndex);
                }
            }
            return retVal;
        }

    static String simpleEncode(Double value, Double max)
        {
            String simpleEncoding = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

            if (max > 0)
            {
                long index = (long) Math.Round( ( value / max) * simpleEncoding.Length - 1);
                if (index > -1 && index < simpleEncoding.Length )
                {
                    if (index < int.MaxValue )
                    {
                        int intIndex = (int) index ;
                        return simpleEncoding.Substring(intIndex, 1);
                    }
                }
            }
            return "A";
        }

    static String GetSize(String xAxis, String yAxis)
        {
            return "chs=" + xAxis + "x" + yAxis;
        }
    }
